package xionglizhen.controller;

import cn.hutool.core.util.StrUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import xionglizhen.entity.User;
import xionglizhen.service.UserService;
import xionglizhen.util.Assert;
import xionglizhen.util.EmailClient;
import xionglizhen.util.RespResult;
import xionglizhen.util.ValidationUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.HttpCookie;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

@Controller
//在类中使用，表示访问该控制器，必须以/login开头
@RequestMapping("/login")
public class LoginController {
    //注入发送邮件的工具类
    @Autowired
    protected EmailClient emailClient;
    //注入用户服务类
    @Autowired
    protected UserService userService;
    //注入验证工具类
    protected ValidationUtils validationUtils;

    //声明会话对象
    //发送邮件后，验证码保存在会话中
    //当执行注册时，从会话中取出验证码数据跟用户输入的验证码做比对
    protected HttpSession session;
    protected HttpCookie cookie;
    protected HttpServletRequest request;
    protected HttpServletResponse response;

    /**
     * 发送验证码
     * 请求方式：post
     * URL地址：/login/sendEmailCode
     *
     * @param email
     * @param map
     * @return
     */
    @PostMapping("/sendEmailCode")
    //表示服务端返回JSON数据【异步一般都是以JSON数据格式进行交互】
    @ResponseBody
    //JSON数据的返回，返回类型使用RespResult
    //String email  前端请求的参数名
    //Map<String, Object> map  会自动创建一个Map对象到方法中
    public RespResult sendEmailCode(String email, Map<String, Object> map) {
        if (StrUtil.isEmpty(email)) {
            //只有静态方法可以使用类名直接访问
            //静态方法内部不能使用this关键字
            return RespResult.fail("邮箱不可为空");
        }
        // 发送验证码
        String verifyCode = emailClient.sendEmailCode(email);
        //把邮箱地址，验证码，有效期写入会话对象中
        map.put("email", email);
        map.put("code", verifyCode);
        map.put("time", new Date());
        //写入会话对象中
        session.setAttribute("EMAIL_CODE" + email, map);
        return RespResult.success("发送成功");
    }

    /**
     * 注册
     * 请求方式：post
     * URL地址：/login/register
     *
     * @param user
     * @param code
     * @return
     */
    @PostMapping("/register")
    @ResponseBody
    public RespResult register(User user, String code) {
        String email = user.getUserEmail();

        //手机号码验证
        if (Assert.isEmpty(user.getUserTel())) {
            return RespResult.fail("手机号码不能为空！");
        } else {
            if (!(ValidationUtils.validatePhoneNumber(user.getUserTel()))) {
                return RespResult.fail("手机号码格式错误！");
            }
        }
        //邮箱地址验证
        if (Assert.isEmpty(email)) {
            return RespResult.fail("邮箱地址不能为空！");
        } else {
            if (!(ValidationUtils.validateEmail(user.getUserEmail()))) {
                return RespResult.fail("邮箱地址格式错误！");
            }
        }

        //1获取session数据
        Map<String, Object> codeData = (Map<String, Object>) session.getAttribute("EMAIL_CODE" + email);
        if (codeData == null) {
            return RespResult.fail("请输入验证码！");
        }
        //从codeData数据中获取验证码code
        String sentCode = (String) codeData.get("code");
        //2 验证有效期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime((Date) codeData.get("time"));
        calendar.add(Calendar.MINUTE, 5);
        if (System.currentTimeMillis() > calendar.getTime().getTime()) {
            session.removeAttribute("EMAIL_CODE" + email);
            return RespResult.fail("验证码已经超时！");
        }
        if (!sentCode.equals(code)) {
            return RespResult.fail("验证码错误！");
        }
        //3判断用户是否唯一
        User query = userService.findUserAccount(user);
        if (Assert.notEmpty(query)) {
            return RespResult.fail("账户已被注册！");
        }
        user.setRoleStatus(0);
        user.setImgPath("https://moti-cloud-v2.oss-cnbeijing.aliyuncs.com/Snipaste_2022-05-01_15-37-01.png");
        userService.save(user);
        return RespResult.success("注册成功", user);
    }

    /**
     * 登录
     * 请求方法：post
     * URL地址：/login/login
     *
     * @param user
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public RespResult login(User user) {
        if (Assert.notEmpty(user)) {
            if (Assert.isEmpty(userService.findUserAccount(user))) {
                return RespResult.fail("账户尚未注册！");
            } else if (!(user.getUserPwd().equals(userService.findUserAccount(user).getUserPwd()))) {
                return RespResult.fail("密码错误！");
            }
        }
        user = userService.findUserAccount(user);
        user.setUpdateTime(new Date());
        userService.saveOrUpdate(user);
        session.setAttribute("loginUser", user);
        session.setAttribute("loginStatus", 1);
        return RespResult.success("登录成功！");
    }

    /**
     * 在每个子类方法调用之前先调用
     */
    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
        //初始化请求对象 响应对象 会话对象
        this.request = request;
        this.response = response;
        this.session = request.getSession(true);
        //loginUser = (User) session.getAttribute("loginUser");
        //session.setAttribute("kindList", illnessKindService.findList());
    }


}
